///**
// * Licensed to the Apache Software Foundation (ASF) under one
// * or more contributor license agreements. See the NOTICE file
// * distributed with this work for additional information
// * regarding copyright ownership. The ASF licenses this file
// * to you under the Apache License, Version 2.0 (the
// * "License"); you may not use this file except in compliance
// * with the License. You may obtain a copy of the License at
// *
// *   http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing,
// * software distributed under the License is distributed on an
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// * KIND, either express or implied. See the License for the
// * specific language governing permissions and limitations
// * under the License.
// */

//using System;
//using System.Collections.Generic;
//using System.Threading;
//using Thrift.Collections;
//using Thrift.Protocol;
//using Thrift.Transport;

//namespace Thrift.Server
//{
//    /// <summary>
//    /// Server that uses C# threads (as opposed to the ThreadPool) when handling requests
//    /// </summary>
//    public class TThreadedServer : TServer
//    {
//        private const int DEFAULT_MAX_THREADS = 100;
//        private volatile bool stop = false;
//        private readonly int maxThreads;

//        private Queue<TTransport> clientQueue;
//        private THashSet<Thread> clientThreads;
//        private object clientLock;
//        private Thread workerThread;

//        public TThreadedServer(TProcessor processor, TServerTransport serverTransport)
//            : this(processor, serverTransport,
//                 new TTransportFactory(), new TTransportFactory(),
//                 new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
//                 DEFAULT_MAX_THREADS, DefaultLogDelegate)
//        {
//        }

//        public TThreadedServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
//            : this(processor, serverTransport,
//                 new TTransportFactory(), new TTransportFactory(),
//                 new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
//                 DEFAULT_MAX_THREADS, logDelegate)
//        {
//        }


//        public TThreadedServer(TProcessor processor,
//                                 TServerTransport serverTransport,
//                                 TTransportFactory transportFactory,
//                                 TProtocolFactory protocolFactory)
//            : this(processor, serverTransport,
//                 transportFactory, transportFactory,
//                 protocolFactory, protocolFactory,
//                 DEFAULT_MAX_THREADS, DefaultLogDelegate)
//        {
//        }

//        public TThreadedServer(TProcessor processor,
//                                 TServerTransport serverTransport,
//                                 TTransportFactory inputTransportFactory,
//                                 TTransportFactory outputTransportFactory,
//                                 TProtocolFactory inputProtocolFactory,
//                                 TProtocolFactory outputProtocolFactory,
//                                 int maxThreads, LogDelegate logDel)
//            : base(processor, serverTransport, inputTransportFactory, outputTransportFactory,
//                  inputProtocolFactory, outputProtocolFactory, logDel)
//        {
//            this.maxThreads = maxThreads;
//            clientQueue = new Queue<TTransport>();
//            clientLock = new object();
//            clientThreads = new THashSet<Thread>();
//        }

//        /// <summary>
//        /// Use new Thread for each new client connection. block until numConnections < maxThreads
//        /// </summary>
//        public override void Serve()
//        {
//            try
//            {
//                //start worker thread
//                workerThread = new Thread(new ThreadStart(Execute));
//                workerThread.Start();
//                serverTransport.Listen();
//            }
//            catch (TTransportException ttx)
//            {
//                logDelegate("Error, could not listen on ServerTransport: " + ttx);
//                return;
//            }

//            while (!stop)
//            {
//                int failureCount = 0;
//                try
//                {
//                    TTransport client = serverTransport.Accept();
//                    lock (clientLock)
//                    {
//                        clientQueue.Enqueue(client);
//                        Monitor.Pulse(clientLock);
//                    }
//                }
//                catch (TTransportException ttx)
//                {
//                    if (stop)
//                    {
//                        logDelegate("TThreadPoolServer was shutting down, caught " + ttx);
//                    }
//                    else
//                    {
//                        ++failureCount;
//                        logDelegate(ttx.ToString());
//                    }

//                }
//            }

//            if (stop)
//            {
//                try
//                {
//                    serverTransport.Close();
//                }
//                catch (TTransportException ttx)
//                {
//                    logDelegate("TServeTransport failed on close: " + ttx.Message);
//                }
//                stop = false;
//            }
//        }

//        /// <summary>
//        /// Loops on processing a client forever
//        /// threadContext will be a TTransport instance
//        /// </summary>
//        /// <param name="threadContext"></param>
//        private void Execute()
//        {
//            while (!stop)
//            {
//                TTransport client;
//                Thread t;
//                lock (clientLock)
//                {
//                    //don't dequeue if too many connections
//                    while (clientThreads.Count >= maxThreads)
//                    {
//                        Monitor.Wait(clientLock);
//                    }

//                    while (clientQueue.Count == 0)
//                    {
//                        Monitor.Wait(clientLock);
//                    }

//                    client = clientQueue.Dequeue();
//                    t = new Thread(new ParameterizedThreadStart(ClientWorker));
//                    clientThreads.Add(t);
//                }
//                //start processing requests from client on new thread
//                t.Start(client);
//            }
//        }

//        private void ClientWorker(Object context)
//        {
//            TTransport client = (TTransport)context;
//            TTransport inputTransport = null;
//            TTransport outputTransport = null;
//            TProtocol inputProtocol = null;
//            TProtocol outputProtocol = null;
//            try
//            {
//                using (inputTransport = inputTransportFactory.GetTransport(client))
//                {
//                    using (outputTransport = outputTransportFactory.GetTransport(client))
//                    {
//                        inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
//                        outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
//                        while (processor.Process(inputProtocol, outputProtocol))
//                        {
//                            //keep processing requests until client disconnects
//                        }
//                    }
//                }
//            }
//            catch (TTransportException)
//            {
//            }
//            catch (Exception x)
//            {
//                logDelegate("Error: " + x);
//            }

//            lock (clientLock)
//            {
//                clientThreads.Remove(Thread.CurrentThread);
//                Monitor.Pulse(clientLock);
//            }
//            return;
//        }

//        public override void Stop()
//        {
//            stop = true;
//            serverTransport.Close();
//            //clean up all the threads myself
//            workerThread.Abort();
//            foreach (Thread t in clientThreads)
//            {
//                t.Abort();
//            }
//        }
//    }
//}
